_itertools.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. from itertools import filterfalse
  2. def unique_everseen(iterable, key=None):
  3. "List unique elements, preserving order. Remember all elements ever seen."
  4. # unique_everseen('AAAABBBCCDAABBB') --> A B C D
  5. # unique_everseen('ABBCcAD', str.lower) --> A B C D
  6. seen = set()
  7. seen_add = seen.add
  8. if key is None:
  9. for element in filterfalse(seen.__contains__, iterable):
  10. seen_add(element)
  11. yield element
  12. else:
  13. for element in iterable:
  14. k = key(element)
  15. if k not in seen:
  16. seen_add(k)
  17. yield element
  18. # copied from more_itertools 8.8
  19. def always_iterable(obj, base_type=(str, bytes)):
  20. """If *obj* is iterable, return an iterator over its items::
  21. >>> obj = (1, 2, 3)
  22. >>> list(always_iterable(obj))
  23. [1, 2, 3]
  24. If *obj* is not iterable, return a one-item iterable containing *obj*::
  25. >>> obj = 1
  26. >>> list(always_iterable(obj))
  27. [1]
  28. If *obj* is ``None``, return an empty iterable:
  29. >>> obj = None
  30. >>> list(always_iterable(None))
  31. []
  32. By default, binary and text strings are not considered iterable::
  33. >>> obj = 'foo'
  34. >>> list(always_iterable(obj))
  35. ['foo']
  36. If *base_type* is set, objects for which ``isinstance(obj, base_type)``
  37. returns ``True`` won't be considered iterable.
  38. >>> obj = {'a': 1}
  39. >>> list(always_iterable(obj)) # Iterate over the dict's keys
  40. ['a']
  41. >>> list(always_iterable(obj, base_type=dict)) # Treat dicts as a unit
  42. [{'a': 1}]
  43. Set *base_type* to ``None`` to avoid any special handling and treat objects
  44. Python considers iterable as iterable:
  45. >>> obj = 'foo'
  46. >>> list(always_iterable(obj, base_type=None))
  47. ['f', 'o', 'o']
  48. """
  49. if obj is None:
  50. return iter(())
  51. if (base_type is not None) and isinstance(obj, base_type):
  52. return iter((obj,))
  53. try:
  54. return iter(obj)
  55. except TypeError:
  56. return iter((obj,))